#include "GLES/gl.h"
#include "GLES/egl.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>


#define SECONDS_TO_RUN      10
#define float2fixed(a)  (int)((a)*(1<<16))
#define fixed2float(a)  (((float)a)/(1<<16))

#define TEXTURE_SIZE 64
static GLubyte texture_image[TEXTURE_SIZE][TEXTURE_SIZE][4];

GLfloat texture_coords[] =
{
  0.0, 0.0,
  1.0, 0.0,
  1.0, 1.0,
};

static void make_texture_image()
{
  int i,j;
  for (i=0; i<TEXTURE_SIZE; i++)
  {
    for (j=0; j<TEXTURE_SIZE; j++)
    {
      if ((i & 0x8) == (j & 0x8))
      {
        texture_image[i][j][0] = (GLubyte)0x0;
        texture_image[i][j][1] = (GLubyte)0x0;
        texture_image[i][j][2] = (GLubyte)0x0;
      }
      else
      {
        texture_image[i][j][0] = (GLubyte)0xff;
        texture_image[i][j][1] = (GLubyte)0xff;
        texture_image[i][j][2] = (GLubyte)0xff;
      }
      texture_image[i][j][3] = (GLubyte)0xff;
    }
  }
}


const EGLint attrib_list[]=
{
  EGL_BUFFER_SIZE,  EGL_DONT_CARE,
  //EGL_SURFACE_TYPE, EGL_DONT_CARE,
  EGL_RED_SIZE,     8,
  EGL_GREEN_SIZE,   8,
  EGL_BLUE_SIZE,    8,
  EGL_DEPTH_SIZE,   8,
  EGL_STENCIL_SIZE, EGL_DONT_CARE,
  EGL_NONE
};

EGLDisplay  display;
EGLConfig   config;
EGLContext  context;
EGLSurface  surface;
EGLint      width, height;

static const GLbyte vertices[3*3]=
{
  -1, 1, 0,
  1,-1, 0,
  1, 1, 0
};

static const GLubyte colors[3*4]=
{
  255,  0,  0,  255,
  0,255,  0,  255,
  0,  0,255,  255
};

static GLfloat xRotate = 0.0;

void SetupGLSystem()
{
  glShadeModel(GL_SMOOTH);
  glDisable(GL_CULL_FACE);
  glClearColor(0.f, 0.f, 0.1f, 1.f);
  glClearDepthf(1.0f);
  glEnable(GL_DEPTH_TEST);
  glDisable(GL_DEPTH_TEST);
  glDepthMask(1);
  glDepthFunc(GL_LESS);

  //glViewport(0, 0, width, height);
  glMatrixMode(GL_PROJECTION);
  glFrustumf(-1.0f, 1.0f, -1.0f, 1.0f, 3.0f, 1000.0f);
  glMatrixMode(GL_MODELVIEW);

  glEnable(GL_TEXTURE_2D);
}

void SetupSceneData()
{
  make_texture_image();

  glVertexPointer(3, GL_BYTE, 0, vertices);
  //glColorPointer(4, GL_UNSIGNED_BYTE, 0, colors);
  glTexCoordPointer(2, GL_FLOAT, 0, texture_coords);

  glEnableClientState(GL_VERTEX_ARRAY);
  glEnableClientState(GL_COLOR_ARRAY);
  glEnableClientState(GL_TEXTURE_COORD_ARRAY);

  glTexImage2D(GL_TEXTURE_2D,
               0,
               GL_RGBA,
               TEXTURE_SIZE,
               TEXTURE_SIZE,
               0,
               GL_RGBA,
               GL_UNSIGNED_BYTE,
               texture_image);

  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}

void RenderFrame()
{
  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  glLoadIdentity();

  glTranslatef(0,0,-5.0f);
  xRotate += 2.0;
  glRotatef(xRotate,0.0,1.0,0.0);

  //glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
  glDrawArrays(GL_TRIANGLES, 0, 3);
  glFinish();
}

void InitEGLSystem()
{
  int numOfConfigs;
  display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
  eglInitialize(display, NULL, NULL);
  eglGetConfigs(display, &config, 1, &numOfConfigs);
  eglChooseConfig(display, attrib_list, &config, 1, &numOfConfigs);
  surface = eglCreateWindowSurface(display, config, NULL, NULL);
  context = eglCreateContext(display, config, EGL_NO_CONTEXT, NULL);
  eglMakeCurrent(display, surface, surface, context);
  eglSwapBuffers(display, surface);

  eglQuerySurface(display, surface, EGL_WIDTH, &width);
  eglQuerySurface(display, surface, EGL_HEIGHT, &height);
  printf("width: %d, height %d\n", width, height);
}

void TermEGLSystem()
{
  eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
  eglDestroySurface(display, surface);
  eglDestroyContext(display, context);
  eglTerminate(display);
}

int main(int argc, char* argv[])
{
  struct timeval  tv;
  double          t0 = 0.0;
  double          t1 = 0.0;

  //signal(SIGTERM , signal_handler);
  //signal(SIGKILL , signal_handler);
  //signal(SIGSTOP , signal_handler);
  //signal(SIGINT  , signal_handler);

  InitEGLSystem();

  SetupGLSystem();
  SetupSceneData();

  // Grab a starting timestamp.
  while (!stop)
  {
    RenderFrame();
    eglSwapBuffers(display, surface);

  }

  TermEGLSystem();
  return 0;
}
